package com.mrogrape.notepad.ui;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;

import javax.swing.DefaultListModel;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.SwingConstants;
import javax.swing.border.EtchedBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import com.mrogrape.notepad.data.ViewContext;



public class SortItemDialog extends JDialog {


	/** serialVersionUID */
	private static final long serialVersionUID = 1L;
	
	public SortItemDialog(Frame parent,String title,List sortedList) {
		super(parent,title,true);

		this.listModel = new SortedListModel(sortedList);
		this.initComponents();
		this.updateButonState();
	}

	private void initComponents() {
		this.setSize(new Dimension(550, 300));

		JPanel buttonPanel = new JPanel();
		this.getContentPane().add(buttonPanel, BorderLayout.EAST);

		this.moveUpBtn = new JButton("Move Up");
		this.moveUpBtn.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				SortItemDialog.this.moveUpBtnActionPerformed(arg0);
			}
		});

		this.moveDownBtn = new JButton("Move Down");
		this.moveDownBtn.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				SortItemDialog.this.moveDownBtnActionPerformed(arg0);
			}
		});

		this.removeBtn = new JButton("Remove");
		this.removeBtn.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				SortItemDialog.this.removeBtnActionPerformed(arg0);
			}
		});

		this.removeAllBtn = new JButton("Remove All");
		this.removeAllBtn.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				SortItemDialog.this.removeAllBtnActionPerformed(arg0);
			}
		});

		this.okBtn = new JButton("OK");
		this.okBtn.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				SortItemDialog.this.okBtnActionPerformed(arg0);
			}
		});
		GroupLayout gl_buttonPanel = new GroupLayout(buttonPanel);
		gl_buttonPanel.setHorizontalGroup(
				gl_buttonPanel.createParallelGroup(Alignment.LEADING)
				.addGroup(gl_buttonPanel.createSequentialGroup()
						.addGroup(gl_buttonPanel.createParallelGroup(Alignment.LEADING)
								.addGroup(Alignment.TRAILING, gl_buttonPanel.createSequentialGroup()
										.addContainerGap(16, Short.MAX_VALUE)
										.addComponent(this.removeBtn))
										.addGroup(Alignment.TRAILING, gl_buttonPanel.createSequentialGroup()
												.addGap(16)
												.addComponent(this.moveDownBtn, GroupLayout.DEFAULT_SIZE, 93, Short.MAX_VALUE))
												.addGroup(Alignment.TRAILING, gl_buttonPanel.createSequentialGroup()
														.addContainerGap(16, Short.MAX_VALUE)
														.addComponent(this.moveUpBtn))
														.addGroup(gl_buttonPanel.createSequentialGroup()
																.addGap(16)
																.addGroup(gl_buttonPanel.createParallelGroup(Alignment.LEADING)
																		.addComponent(this.okBtn, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 93, Short.MAX_VALUE)
																		.addComponent(this.removeAllBtn, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
																		.addContainerGap())
		);
		gl_buttonPanel.setVerticalGroup(
				gl_buttonPanel.createParallelGroup(Alignment.LEADING)
				.addGroup(gl_buttonPanel.createSequentialGroup()
						.addContainerGap()
						.addComponent(this.moveUpBtn)
						.addPreferredGap(ComponentPlacement.RELATED)
						.addComponent(this.moveDownBtn)
						.addGap(18)
						.addComponent(this.removeBtn)
						.addPreferredGap(ComponentPlacement.RELATED)
						.addComponent(this.removeAllBtn)
						.addPreferredGap(ComponentPlacement.RELATED, 97, Short.MAX_VALUE)
						.addComponent(this.okBtn)
						.addContainerGap())
		);
		gl_buttonPanel.linkSize(SwingConstants.HORIZONTAL, new Component[] {this.moveUpBtn, this.moveDownBtn, this.removeBtn, this.removeAllBtn});
		buttonPanel.setLayout(gl_buttonPanel);

		this.listView = new JList(this.listModel);
		this.listView.setFont(ViewContext.getDefaultMonospacedFont());
		this.listView.addListSelectionListener(new ListSelectionListener() {
			@Override
			public void valueChanged(ListSelectionEvent arg0) {
				SortItemDialog.this.listViewValueChanged(arg0);
			}
		});
		this.listView.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null));
		this.getContentPane().add(this.listView, BorderLayout.CENTER);
		this.setLocationRelativeTo(this.getOwner());
	}

	private void listViewValueChanged(ListSelectionEvent arg0) {

		this.updateButonState();
	}

	private void moveUpBtnActionPerformed(ActionEvent arg0) {

		int index = this.listView.getSelectedIndex();
		if(index <= 0){
			return;
		}

		Object element = this.listModel.getElementAt(index);
		this.listModel.remove(index);
		this.listModel.insertElementAt(element, index - 1);
		this.listView.setSelectedIndex(index - 1);
		
		this.updateButonState();
	}

	private void moveDownBtnActionPerformed(ActionEvent arg0) {

		int index = this.listView.getSelectedIndex();
		if((index == -1) || (index == this.listModel.getSize() - 1)){
			return;
		}

		Object element = this.listModel.getElementAt(index);
		this.listModel.remove(index);
		this.listModel.insertElementAt(element,index + 1);
		this.listView.setSelectedIndex(index + 1);

		this.updateButonState();
	}

	private void removeBtnActionPerformed(ActionEvent arg0) {

		int index = this.listView.getSelectedIndex();
		if(index != -1){

			this.listModel.remove(index);
		}

		this.updateButonState();
	}

	private void removeAllBtnActionPerformed(ActionEvent arg0) {

		this.listModel.removeAllElements();
		this.updateButonState();
	}

	private void okBtnActionPerformed(ActionEvent arg0) {

		this.setVisible(false);
	}

	private void updateButonState(){

		boolean upEnable = false;
		boolean downEnable = false;
		boolean removeEnable = false;
		boolean removeAllEnable = false;

		int size = this.listModel.getSize();
		int index = this.listView.getSelectedIndex();

		if(size != 0){
			removeAllEnable = true;
		}

		if(index != -1){

			removeEnable = true;
		}

		if((size != 1) && (index != -1) &&(index != size - 1)){

			downEnable = true;
		}

		if((size != 1) && (index > 0)){

			upEnable = true;
		}

		this.moveUpBtn.setEnabled(upEnable);
		this.moveDownBtn.setEnabled(downEnable);
		this.removeBtn.setEnabled(removeEnable);
		this.removeAllBtn.setEnabled(removeAllEnable);
	}

	private SortedListModel listModel;

	private JList listView;
	private JButton moveUpBtn;
	private JButton moveDownBtn;
	private JButton removeBtn;
	private JButton removeAllBtn;
	private JButton okBtn;


	private class SortedListModel extends DefaultListModel{

		/** serialVersionUID */
		private static final long serialVersionUID = 1L;

		SortedListModel(List list){
			this.list = list;

			for(int i = 0; i < list.size(); i ++){

				super.insertElementAt(list.get(i), i);
			}
		}

		@Override
		public void insertElementAt(Object obj, int index) {

			this.list.add(index, obj);
			super.insertElementAt(obj, index);
		}

		@Override
		public Object remove(int index) {

			this.list.remove(index);
			return super.remove(index);
		}

		@Override
		public void removeAllElements() {

			this.list.clear();
			super.removeAllElements();
		}

		private List list;
	}
}
